package cn.ztuo.bitrade.controller;

import cn.ztuo.bitrade.constant.TransactionType;
import cn.ztuo.bitrade.dto.MemberTeamDTO;
import cn.ztuo.bitrade.entity.Short;
import cn.ztuo.bitrade.entity.*;
import cn.ztuo.bitrade.entity.transform.AuthMember;
import cn.ztuo.bitrade.service.*;
import cn.ztuo.bitrade.util.BigDecimalUtils;
import cn.ztuo.bitrade.util.MessageResult;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

import static cn.ztuo.bitrade.constant.SysConstant.SESSION_MEMBER;

@RestController
@Slf4j
@RequestMapping("/relation")
public class RelationController {


    @Autowired
    private RelationService relationService;
    @Autowired
    private MemberWalletService memberWalletService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private SysCfService sysConfigService;
    @Autowired
    private MemberTransactionService transactionService;
    @Autowired
    private AwardService awardService;
    @Autowired
    private ShortService shortService;

    private static final int DEFAULT_DIV_SCALE = 4;
    private static final String CARD="ODFc6HgWvT8VwBYDeJ12BkzFnGHLnYdau2Ep";


    //查询账号是否激活
    protected Boolean activation(Long uid){
        return relationService.findActivation(uid);
    }


    //添加安置关系
    @PostMapping("addRelation")
    @Transactional
    public MessageResult addRelation(
            @SessionAttribute(SESSION_MEMBER) AuthMember user,
            @RequestParam(value = "placeCode") String placeCode
    ){
        Member member = memberService.findOne(user.getId());
        if(member==null) return MessageResult.error(400,"用户不存在");
        Boolean is = this.activation(member.getId());
        if(is) return MessageResult.error(400,"账号已经激活");
        //定义扣除的币种,冻结资产然后安置用户，如果安置从成功，扣除冻结资产
        SysCf coinnumber = sysConfigService.configOneCname("activation");
        SysCf coinname = sysConfigService.configOneCname("activationcoin");
        if(coinnumber ==null || coinname ==null) return MessageResult.error(400,"参数配置错误，请联系管理员");
        String coin = coinname.getValue();
        BigDecimal number  = new BigDecimal(coinnumber.getValue());
        //切割用户安置码，前9位为推荐吗，最后一位区分左右区
        String anzhi = placeCode.trim();
        if(anzhi.trim().length()==0||anzhi.equals("")||anzhi==null) return MessageResult.error(400,"安置码错误");
        String idnumber = anzhi.substring(0,anzhi.length()-2);
        Long code = Long.parseLong(idnumber)/15;
        String position = anzhi.substring(anzhi.length()-1,anzhi.length());
        //查询安置码是否存在
        Member memberparent = memberService.findOne(code);
        if(memberparent==null) return MessageResult.error(400,"安置码不存在");
        Relation parentInof = relationService.findOneInfo(memberparent.getId());
        if(parentInof==null) return MessageResult.error(400,"安置码不存在");
        //位置是否有用户占用
        Boolean isPostion = true;
        int positionTo = 0;
        if(position.equals("L")){
            isPostion =  relationService.checkPosition(memberparent.getId(),1);
            positionTo = 1;
        }else if(position.equals("R")){
            isPostion =   relationService.checkPosition(memberparent.getId(),2);
            positionTo = 2;
        }else{
            return MessageResult.error(400,"安置码不存在");
        }
        if(isPostion) return MessageResult.error(400,"安置码已被占用");

        MemberWallet memberWallet = memberWalletService.findByCoinUnitAndMemberId(coin,member.getId());
        if(!BigDecimalUtils.compare(memberWallet.getBalance(),number)) return MessageResult.error(400,"账户资产不足不能激活");
        MessageResult result =  memberWalletService.freezeBalance(memberWallet,number);
        if(result.getCode()!=0) return MessageResult.error(400,"账户资产不足不能安置激活");
        //如果没有被占用,安置用户
        //获取父级的安置详情
        Relation relation = new Relation();
        relation.setUid(member.getId());
        relation.setUsername(member.getUsername());
        relation.setPid(memberparent.getId());
        relation.setParent(parentInof.getParent()+memberparent.getId().toString()+"|");
        relation.setStatus(1);
        relation.setPosition(positionTo);
        relation.setCreate_time(new Date());
        Long isSuccess  = relationService.save(relation);
        MemberWallet odfWallet = memberWalletService.findByCoinUnitAndMemberId("ODF",member.getId());
        if(isSuccess>0){
            //安置成功，减去冻结金额资金
            memberWalletService.decreaseFrozen(memberWallet.getId(),number);
            //如果有赠送的币锁仓这部分
            SysCf config = sysConfigService.configOneCname("number");
            BigDecimal tg = new BigDecimal(config.getValue());
            if (tg.compareTo(BigDecimal.ZERO) != 0) {
                //创建空投记录
                Short aShort = new Short();
                aShort.setCreateTime(new Date());
                aShort.setDay(100L);
                aShort.setFreed(tg);
                aShort.setNumber(tg);
                aShort.setNowDay(0L);
                aShort.setPeoples(0L);
                aShort.setStatus(1L);
                aShort.setUsername(member.getUsername());
                aShort.setMemberId(member.getId());
                shortService.save(aShort);
                MemberTransaction transaction2 = new MemberTransaction();
                transaction2.setAmount(tg);
                transaction2.setSymbol("ODF");
                transaction2.setAddress("");
                transaction2.setMemberId(member.getId());
                transaction2.setType(TransactionType.GETACTIVATION);
                transaction2.setFee(BigDecimal.ZERO);
                transaction2.setCreateTime(new Date());
                transaction2.setRemark("账号激活空投");
                transaction2.setFromAddress(CARD);
                transaction2.setToAddress(odfWallet.getAddress());
                transaction2.setStatus(1);
                transactionService.save(transaction2);
                if (member.getInviterId() != null) {
                    Short shortInfo = shortService.findByMemberIdAndStatus(member.getInviterId(), 1L);
                    if (shortInfo != null) {
                        Long peoples = shortInfo.getPeoples();
                        BigDecimal freed = shortInfo.getFreed();
                        BigDecimal freedNumber = BigDecimal.ZERO;
                        if (peoples == 0) {
                            freedNumber = BigDecimalUtils.mulRound(shortInfo.getNumber(),new BigDecimal("0.5"),DEFAULT_DIV_SCALE); //剩余的总数量
                            if(freedNumber.compareTo(shortInfo.getFreed())>=0){
                                freedNumber = shortInfo.getFreed();
                            }
                        } else if (peoples == 1) {
                            freedNumber = shortInfo.getFreed();
                        }
                        //如果释放算力大于0，增加余额
                        if (freedNumber.compareTo(BigDecimal.ZERO) > 0) {
                            MemberWallet wallet = memberWalletService.findByCoinUnitAndMemberId("ODF", member.getInviterId());
                            memberWalletService.increaseBalance(wallet.getId(), freedNumber);
                            if(peoples+1>=2){
                                shortInfo.setStatus(2L);
                                shortInfo.setPeoples(2L);
                                shortInfo.setFreed(BigDecimal.ZERO);
                            }else{
                                shortInfo.setPeoples(shortInfo.getPeoples()+1L);
                            }
                            shortInfo.setFreed(BigDecimalUtils.sub(freed,freedNumber));
                            shortService.save(shortInfo);
                            MemberTransaction transaction1 = new MemberTransaction();
                            MemberWallet odfWallet2 = memberWalletService.findByCoinUnitAndMemberId("ODF",member.getInviterId());
                            transaction1.setAmount(freedNumber);
                            transaction1.setSymbol("ODF");
                            transaction1.setAddress("");
                            transaction1.setMemberId(member.getInviterId());
                            transaction1.setType(TransactionType.GETACTIVATIONS);
                            transaction1.setFee(BigDecimal.ZERO);
                            transaction1.setCreateTime(new Date());
                            transaction1.setRemark("账号激活空投释放");
                            transaction2.setFromAddress(CARD);
                            transaction2.setToAddress(odfWallet2.getAddress());
                            transaction2.setStatus(1);
                            transactionService.save(transaction1);
                        }
                    }
                }
            }
            //激活记录
            Award award = new Award();
            award.setNumber(number);
            award.setCreateTime(new Date());
            award.setStatus(1L);
            award.setType(1L);
            award.setUid(member.getId());
            award.setUnit(coin);
            awardService.save(award);
            //添加账单记录
            MemberTransaction transaction = new MemberTransaction();
            transaction.setAmount(number.negate());
            transaction.setSymbol(coin);
            transaction.setAddress("");
            transaction.setMemberId(member.getId());
            transaction.setType(TransactionType.ACTIVATION);
            transaction.setFee(BigDecimal.ZERO);
            transaction.setCreateTime(new Date());
            transaction.setRemark("账号激活");

            transaction.setFromAddress(odfWallet.getAddress());
            transaction.setToAddress(CARD);
            transaction.setStatus(2);

            transactionService.save(transaction);
            return MessageResult.success("账户安置成功");
        }else{
            //安置失败，减去冻结金额，增加余额(解冻)
            memberWalletService.thawBalance(memberWallet.getId(),number);
            relationService.delete(isSuccess);
            return MessageResult.error(400,"账户安置失败，请稍后再试");
        }
    }


    /**
     * 空投释放
     *
     */
    @Scheduled(cron = "0 34 3 * * ?")
    @Transactional()
    public String AutoRedeem() {
        SysCf config = sysConfigService.configOneCname("numberopen");
        if (config.getValue().equals("2")) return "释放未开启";
        log.info("账号激活释放开始");
        List<Short> infos = shortService.findAllByStatus(1L);
        BigDecimal number = BigDecimal.ZERO;
        for (Short info : infos) {
            if (info.getPeoples() == 1) {
                number = BigDecimalUtils.mulRound(BigDecimalUtils.mulRound(info.getNumber(), new BigDecimal("0.5"), DEFAULT_DIV_SCALE), new BigDecimal("0.01"), DEFAULT_DIV_SCALE); //剩余的总数量
                MemberWallet wallet = memberWalletService.findByCoinUnitAndMemberId("ODF", info.getMemberId());
                memberWalletService.increaseBalance(wallet.getId(), number);
            } else if (info.getPeoples() == 0) {
                number = BigDecimalUtils.mulRound(info.getNumber(), new BigDecimal("0.01"), DEFAULT_DIV_SCALE); //剩余的总数量
                if (number.compareTo(info.getFreed()) >= 0) {
                    number = info.getFreed();
                }
                MemberWallet wallet = memberWalletService.findByCoinUnitAndMemberId("ODF", info.getMemberId());
                memberWalletService.increaseBalance(wallet.getId(), number);
            }
            BigDecimal sheng = BigDecimalUtils.sub(info.getFreed(), number);
            info.setFreed(sheng);
            Long day = info.getNowDay() + 1;
            info.setNowDay(day);
            if (day >= 100 || sheng.compareTo(BigDecimal.ZERO) == 0) {
                info.setStatus(2L);
            }
            shortService.save(info);
            MemberTransaction transaction1 = new MemberTransaction();
            transaction1.setAmount(number);
            transaction1.setSymbol("ODF");
            transaction1.setAddress("");
            transaction1.setMemberId(info.getMemberId());
            transaction1.setType(TransactionType.GETACTIVATIONS);
            transaction1.setFee(BigDecimal.ZERO);
            transaction1.setCreateTime(new Date());
            transaction1.setRemark("账号激活空投释放");

//            MemberWallet odfWallet2 = memberWalletService.findByCoinUnitAndMemberId("ODF",info.getMemberId());
//            transaction1.setFromAddress(CARD);
//            transaction1.setToAddress(odfWallet2.getAddress());
//            transaction1.setStatus(1);

            transactionService.save(transaction1);
        }
        log.info("账号激活释放结束");
        return "赠送ODF释放结束";
    }

    /**
     * 获取用户的空投记录
     * @param user
     * @return
     */
    @PostMapping("awardInfo")
    public MessageResult awardInfo(@SessionAttribute(SESSION_MEMBER) AuthMember user){
      Short shorts =   shortService.findOne(user.getId());
      if(shorts==null) return MessageResult.error("data null");
      return MessageResult.getSuccessInstance("success",shorts);
    }

    /**
     * 获取当前用户的直推信息
     */
    @PostMapping("childsUser")
    public MessageResult childsUser(@SessionAttribute(SESSION_MEMBER) AuthMember user){
       List<Member> members =  memberService.findPromotionMember(user.getId());
       Integer h = 0;
       Integer w = 0;
        ArrayList<MemberTeamDTO> team = new ArrayList<>();
        for(Member member:members){
           MemberTeamDTO memberTeamDTO = new MemberTeamDTO();
           memberTeamDTO.setId(member.getId());
           memberTeamDTO.setCreateTime(member.getRegistrationTime());
           memberTeamDTO.setUsername(member.getUsername());
           if(relationService.findActivation(member.getId())){
               memberTeamDTO.setMark(1L);
               ++h;
           }else{
               memberTeamDTO.setMark(0L);
               ++w;
           }
           team.add(memberTeamDTO);
       }
        List<Member> membersAll = memberService.findAllByParentsLike(String.valueOf(user.getId()));
        Integer all = 0;
        for(Member member:membersAll) {
            if(relationService.findActivation(member.getId())){
                ++all;
            }
        }
        HashMap<String,Object> map = new HashMap<>();
        map.put("h",h);
        map.put("w",w);
        map.put("all",all);
        map.put("users",team);
        return MessageResult.getSuccessInstance("success",map);
    }

    /**
     * 获取用户的激活信息和激活需要的币种和数量
     * @param user
     * @return
     */
    @PostMapping("relationInfo")
    public MessageResult relationInfo(@SessionAttribute(SESSION_MEMBER) AuthMember user){
        Boolean is = this.activation(user.getId());
        SysCf coinnumber = sysConfigService.configOneCname("activation");
        SysCf coinname = sysConfigService.configOneCname("activationcoin");
        if(coinnumber ==null || coinname ==null) return MessageResult.error(400,"参数配置错误，请联系管理员");
        String coin = coinname.getValue();
        BigDecimal number  = new BigDecimal(coinnumber.getValue());
        HashMap<String,Object> hashMap = new HashMap<>();
        HashMap<String,String> hashMap1 = new HashMap<>();
        hashMap1.put("coin",coin);
        hashMap1.put("number",number.toString());
        JSONObject jsonObject = JSONObject.fromObject(hashMap1);
        hashMap.put("activationInfo",jsonObject);
        if(is) {
            //账号已激活
            hashMap.put("activationStatus","1");
            Member member = memberService.findOne(user.getId());
            HashMap<String,Object> hashMap2 = new HashMap<>();
            Long

                    rand = member.getId()*15;
            hashMap2.put("left",rand.toString()+"1L");
            hashMap2.put("right",rand.toString()+"2R");
            JSONObject jsonObject1 = JSONObject.fromObject(hashMap2);
            hashMap.put("code",jsonObject1);
            HashMap<String,String> map = relationService.idInfo(user.getId());
            hashMap.put("codeInfo",map);
            return MessageResult.getSuccessInstance("成功",hashMap);
        }else{
            //账号未激活
            hashMap.put("activationStatus","2");
            return MessageResult.getSuccessInstance("成功",hashMap);
        }
    }

    /**
     * 获取某个用户的安置码和安置信息;
     * @param user
     * @return
     */
    @PostMapping("relationInfos")
    public MessageResult relationInfos(@SessionAttribute(SESSION_MEMBER) AuthMember user,String username){
        Member member = memberService.findByUsername(username);
        if(member==null) return  MessageResult.error(400,"用户名不存在");
        Boolean is = this.activation(member.getId());
        HashMap<String,Object> hashMap = new HashMap<>();
        if(is) {
            //账号已激活
            hashMap.put("activationStatus","1");
            HashMap<String,Object> hashMap2 = new HashMap<>();
            Long rand = member.getId()*15;
            hashMap2.put("left",rand.toString()+"1L");
            hashMap2.put("right",rand.toString()+"2R");
            JSONObject jsonObject1 = JSONObject.fromObject(hashMap2);
            hashMap.put("code",jsonObject1);
            HashMap<String,String> map = relationService.idInfo(member.getId());
            hashMap.put("codeInfo",map);
            return MessageResult.getSuccessInstance("成功",hashMap);
        }else{
            //账号未激活
            hashMap.put("activationStatus","2");
            return MessageResult.getSuccessInstance("成功",hashMap);
        }
    }
    /**
     * 输出安置关系图
     * @param user TOken登录
     * @param id 用户ID
     * @return
     */
    @PostMapping("/relationView")
    public Object relationView(
            @SessionAttribute(SESSION_MEMBER) AuthMember user,
            @RequestParam(value = "id",defaultValue = "0") Long id
    ){
        HashMap<String,HashMap<String,Object>> hashMap = new HashMap<>();
        int level = 3;
        if(id == 0) id = user.getId();
        Member member  = memberService.findOne(id);
        if(member==null) id = user.getId();
        for(int i=1;i<=level;i++){
            if(i==1){
                HashMap<String,Object> hashMap1 = new HashMap<>();
                hashMap1.put("uid",member.getId());
                hashMap1.put("username",member.getUsername());
                Long rand = member.getId()*15;
                hashMap1.put("left",rand.toString()+"1L");
                hashMap1.put("right",rand.toString()+"2R");
                hashMap.put("1",hashMap1);
            }else if(i==2){
                HashMap<String,Object> hashMap2 = new HashMap<>();
                hashMap2.put("1",this.selectRelation(id,1));
                hashMap2.put("2",this.selectRelation(id,2));
                hashMap.put("2",hashMap2);
            }else if(i==3){
                HashMap<String,Object> hashMap3 = new HashMap<>();
                HashMap<String, Object> three = hashMap.get("2");
                if(three.get("1").equals("0")){
                    hashMap3.put("1","0");
                    hashMap3.put("2","0");
                }else{
                    HashMap<String,String> map = (HashMap<String, String>) three.get("1");
                    for(String key:map.keySet()){
                        if(key.equals("uid")){
                            hashMap3.put("1",this.selectRelation(Long.parseLong(map.get(key)),1));
                            hashMap3.put("2",this.selectRelation(Long.parseLong(map.get(key)),2));
                        }
                    }
                }
                if(three.get("2").equals("0")){
                    hashMap3.put("3","0");
                    hashMap3.put("4","0");
                }else{
                    HashMap<String,String> map = (HashMap<String, String>) three.get("2");
                    for(String key:map.keySet()){
                        if(key.equals("uid")){
                            hashMap3.put("3",this.selectRelation(Long.parseLong(map.get(key)),1));
                            hashMap3.put("4",this.selectRelation(Long.parseLong(map.get(key)),2));
                        }
                    }
                }
                hashMap.put("3",hashMap3);
            }
        }
        JSONObject jsonObject = JSONObject.fromObject(hashMap);
        return MessageResult.getSuccessInstance("成功",jsonObject);
    }

    /**
     * 返回UID
     * @param map
     * @return
     */
    public String checkData(HashMap<String,String> map){
        String value="";
        for (Map.Entry<String,String>entry:map.entrySet()) {
            if(entry.getKey().equals("uid")){
                value = entry.getValue();
                break;
            }
        }
        return value;
    }

    /**
     * 获取当前用户的左区和右区信息
     * 没有就返回字符串0
     * @param uid
     * @param position
     * @return
     */
    protected Object selectRelation(Long uid,int position){
        Relation relation = relationService.checkPosition2(uid,position);
        if(relation==null){
          return "0";
        }
        HashMap<String,String> hashMapTo = new HashMap<>();
        hashMapTo.put("username",relation.getUsername());
        hashMapTo.put("uid",String.valueOf(relation.getUid()));
        Long rand = relation.getUid()*15;
        hashMapTo.put("left",rand.toString()+"1L");
        hashMapTo.put("right",rand.toString()+"2R");
        return hashMapTo;
    }

}
